From 5ee95b1775c0aed545b30334fc240c551479d450 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 1 Sep 2016 10:42:23 -0700 Subject: [PATCH] Test a crate that is both a plugin and a proc macro --- src/cargo/util/toml.rs | 9 +++++++++ tests/rustc-macro.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 811e58b49..15e524631 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -1011,6 +1011,15 @@ impl TomlTarget { } fn validate_crate_type(&self) -> CargoResult<()> { + // Per the Macros 1.1 RFC: + // + // > Initially if a crate is compiled with the rustc-macro crate type + // > (and possibly others) it will forbid exporting any items in the + // > crate other than those functions tagged #[rustc_macro_derive] and + // > those functions must also be placed at the crate root. + // + // A plugin requires exporting plugin_registrar so a crate cannot be + // both at once. if self.plugin == Some(true) && self.rustc_macro == Some(true) { Err(human("lib.plugin and lib.rustc-macro cannot both be true".to_string())) } else { diff --git a/tests/rustc-macro.rs b/tests/rustc-macro.rs index fe49b359d..f3d618b12 100644 --- a/tests/rustc-macro.rs +++ b/tests/rustc-macro.rs @@ -144,3 +144,44 @@ fn impl_and_derive() { assert_that(client.cargo("run"), execs().with_status(0).with_stdout("X { success: true }")); } + +#[test] +fn plugin_and_rustc_macro() { + if !is_nightly() { + return; + } + + let questionable = project("questionable") + .file("Cargo.toml", r#" + [package] + name = "questionable" + version = "0.0.1" + authors = [] + + [lib] + plugin = true + rustc-macro = true + "#) + .file("src/lib.rs", r#" + #![feature(plugin_registrar, rustc_private)] + #![feature(rustc_macro, rustc_macro_lib)] + + extern crate rustc_plugin; + use rustc_plugin::Registry; + + extern crate rustc_macro; + use rustc_macro::TokenStream; + + #[plugin_registrar] + pub fn plugin_registrar(reg: &mut Registry) {} + + #[rustc_macro_derive(Questionable)] + pub fn questionable(input: TokenStream) -> TokenStream { + input + } + "#); + + let msg = " lib.plugin and lib.rustc-macro cannot both be true"; + assert_that(questionable.cargo_process("build"), + execs().with_status(101).with_stderr_contains(msg)); +} -- 2.30.2